/*
 *  孵化池
 *  
 *   孵化规则，
 *     1 初始3个孵化对象，第一个剩余两小时。 第二个剩余四小时。第三个剩余六小时。正常孵化时间为12小时。每小时获得一次数值晋升（等级提升）。
 *     2 每小时补充一个孵化对象，上限为同时孵化6人。
 *     3 玩家通过孵化池研究可以不断追家当前的孵化数量。
 *     4 孵化池研究5级。每1，3，5，10，15，30。可追加一个同时孵化数量
 *     
 *     5 进入孵化池初始等级（1-5），所有英雄最高50等级
 * 
 */
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using SimpleJson;

namespace Dolls
{
    public class cDollsHatchDefine
    {
        /// <summary>
        /// 全部孵化时间
        /// </summary>
        public const long Const_HatchALLT = (long)Const_StepMax * 3600 * 10000000;
        /// <summary>
        /// 每次孵化时间
        /// </summary>
        public const long Const_HatchStepMS = (long)3600 * 10000000; //孵化时间ms
        /// <summary>
        /// 孵化池最少可孵化数量
        /// </summary>
        public const int Const_HatchMinNum = 5; //最少是孵化5个
        /// <summary>
        /// 最多可进行12次进化
        /// </summary>
        public const int Const_StepMax = 12; //最多12次进化

        /// <summary>
        /// 孵化池中的最多孵化数量
        /// </summary>
        public const int Const_HatchPageNumMax = 12;
    }

    /// <summary>
    /// 孵化池数据
    /// </summary>
    public class cDollsHatchData
    {
        public long mDollResId; 
        public long mBt;  //开始时间
        public int mStep;  //进化次数
        public int mHatchIndex; //
        public bool mIsUpdateNow=false; //最近是否升级
        /// <summary>
        /// 强制进化增加的次数，每次增加1个小时
        /// </summary>-
        public int mStepAdd;

        /// <summary>
        /// 进化
        /// </summary>
        public void Evolution()
        {
            cDoll doll = CDollsManager.Inst.Find(mDollResId);
            doll.mLevel++;

            int num = 1;
            if (doll.mLevel < 10)
                num = 3;
            else if (doll.mLevel < 20)
                num = 2;
            else
                num = 1;

            for(int i = 0; i<num; i++)
            {
                if(doll.mResData.mainType == eDollsType.FIGHTER )
                {
                    int r = UnityEngine.Random.Range(0, 3);
                    if (r == 0)
                    {
                        doll.mAtkAdd += 1;
                        doll.mAtkAddNew = 1;
                    }
                       
                    else if (r == 1)
                    {
                        doll.mDefAdd += 1;
                        doll.mDefAddNew = 1;
                    }
                        
                    else if (r == 2)
                    {
                        doll.mDodgeAdd += 1;
                        doll.mDodgeAddNew = 1;
                    }
                }
                else if (doll.mResData.mainType == eDollsType.ASSIST)
                {
                    int r = UnityEngine.Random.Range(0, 3);
                    if (r == 0)
                    {
                        doll.mCollectAdd += 1;
                        doll.mCollectAddNew = 1;
                    }
                    else if (r == 1)
                    {
                        doll.mProductAdd += 1;
                        doll.mProductAddNew = 1;
                    }
                    else if (r == 2)
                    {
                        doll.mResearchAdd += 1;
                        doll.mResearchAddNew = 1;
                    }
                }

            }

            mIsUpdateNow = true;
            mStep++;

            doll.Save();
            PlayerPrefs.Save();
        }

        public void Force_Evolution()
        {
            if(mStep<10)
            {
                mStepAdd++;
                Evolution();
            }
            Save();
        }

        public void Save()
        {
            JsonObject data = new JsonObject();
            data.Add("mDollResId", mDollResId);
            data.Add("mBt", mBt);
            data.Add("mStep", mStep);
            data.Add("mStepAdd", mStepAdd);
            string str = data.ToString();
            PlayerPrefs.SetString("hatch_" + mHatchIndex, str);
            PlayerPrefs.Save();
        }

        public void Load()
        {
            string str = PlayerPrefs.GetString("hatch_" + mHatchIndex, "");
            if (!string.IsNullOrEmpty(str))
            {
                JsonObject o = (JsonObject)SimpleJson.SimpleJson.DeserializeObject(str);

                mDollResId = Convert.ToInt64(o["mDollResId"]);
                mBt = Convert.ToInt64(o["mBt"]);
                mStep = Convert.ToInt32(o["mStep"]);
                mStepAdd = Convert.ToInt32(o["mStepAdd"]);
            }
            else
            {
                ReInit();
            }
        }

        public void ReInit()
        {
            mStep = 0;
        }

        public void CheckUpdate()
        {
            if(mStep < cDollsHatchDefine.Const_StepMax )
            {
                //计算升级次数
                long allt = DateTime.Now.Ticks + mStepAdd * cDollsHatchDefine.Const_HatchStepMS - mBt;
                long upnum = allt / cDollsHatchDefine.Const_HatchStepMS;
                upnum = upnum - mStep;
                if(upnum>0)
                {
                    for (int i = 0; i < upnum; i++)
                    {
                        if (mStep >= cDollsHatchDefine.Const_StepMax)
                            break;
                        Evolution();
                    }
                }
            }
        }

        public float GetHatchProgress()
        {
            long allt = DateTime.Now.Ticks + mStepAdd * cDollsHatchDefine.Const_HatchStepMS - mBt;
            double perc = (double)allt / (double)cDollsHatchDefine.Const_HatchALLT;
            return Mathf.Clamp01((float)perc);
        }
    }


    /// <summary>
    /// 孵化池
    /// </summary>
    public class cDollsHatch : Instance<cDollsHatch>
    {
        List<cDollsHatchData> mHatchs = new List<cDollsHatchData>();
        public float mHatchBT; //每次刷新数据
        /// <summary>
        /// 当前可以孵化数量
        /// </summary>
        public int mNowMaxNum = cDollsHatchDefine.Const_HatchMinNum; 
        public long mLastAddOneT = 0;//上次新增的孵化时间

        public List<cDollsHatchData> GetHatchArr()
        {
            return mHatchs;
        }

        public cDollsHatchData FindByIndex(int index)
        {
            for(int i=0; i<mHatchs.Count; i++)
            {
                if (mHatchs[i].mHatchIndex == index)
                    return mHatchs[i];
            }
            return null;
           // return mHatchs.Find(c => c.mDollResId == resId);
        }

        public void UpdateHatch()
        {
            //检查是否有升级的需要。如果有则升级。
            foreach(var v in mHatchs)
            {
                v.CheckUpdate();
            }
        }

        public cDollsHatchData [] CheckHatchFinish()
        {
            return mHatchs.FindAll(c => c.mStep >= cDollsHatchDefine.Const_StepMax).ToArray();
        }

        public void RemoveAllHatchFinishDolls()
        {
            bool change = false;
            for (int i = 0; i < mHatchs.Count; i++)
            {
                if (mHatchs[i].mStep >= cDollsHatchDefine.Const_StepMax)
                {
                    cDoll doll = CDollsManager.Inst.Find(mHatchs[i].mDollResId);
                    doll.mHatchingIndex = 2; // 孵化结束
                    doll.Save();
                    PlayerPrefs.Save();

                    mHatchs.RemoveAt(i);
                    i--;
                    change = true;
                }
            }

            if(change)
            {
                for (int i = 0; i < mHatchs.Count; i++)
                {
                    mHatchs[i].mHatchIndex = i;
                }
                Save();
            }
        }

        /// <summary>
        /// 检查是否要新增数据
        /// </summary>
        public void CheckAddNewData()
        {
            //看看孵化池是不是满了
            //不满，计算刷新时间，计算可以新加入的数量
            //把能加入的新的孵化加入
            int num = mHatchs.Count;
            if( num < mNowMaxNum )
            {
                int addNum = (int)(DateTime.Now.Ticks - mLastAddOneT) / 10000000 / 3600;
                addNum = Mathf.Min(addNum, mNowMaxNum - num);
                addNum = Mathf.Max(addNum, 0);

                if(addNum == 0 && num == 0 )
                {
                    addNum = 1;
                    mLastAddOneT = DateTime.Now.Ticks;
                }

                if(addNum>0)
                {
                    AddHatch(addNum);
                    Save();
                }
                
            }
        }

        private void AddHatch(int addNum)
        {
            for(int i=0; i<addNum; i++)
            {
                cDoll doll = CDollsManager.Inst.GetRandomNoHatchOne();
                doll.mHatchingIndex = 1;

                cDollsHatchData data = new cDollsHatchData();
                data.mDollResId = doll.mResData.mResId;
                data.mBt = DateTime.Now.Ticks;
                data.mStep = 0;
                data.mHatchIndex = mHatchs.Count;

                mHatchs.Add(data);
            }
            Save();
        }

        public void Load()
        {
            mHatchs.Clear();
            int hatchNum = PlayerPrefs.GetInt("HatchNum", 0);
            string str = PlayerPrefs.GetString("mLastAddOneT", "0");
            mLastAddOneT = long.Parse( str );
            for (int i=0; i<hatchNum; i++)
            {
                cDollsHatchData data = new cDollsHatchData();
                data.mHatchIndex = i;
                data.Load();
                mHatchs.Add(data);
            }
        }

        public void Save()
        {
            PlayerPrefs.SetInt("HatchNum", mHatchs.Count);
            PlayerPrefs.SetString("mLastAddOneT", mLastAddOneT.ToString());
            for(int i=0;i<mHatchs.Count;i++)
            {
                mHatchs[i].Save();
            }
            PlayerPrefs.Save();
        }
    }

}

